package com.settlement.system.common.util.common;

import lombok.extern.slf4j.Slf4j;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 
 * 日期时间工具类
 * 
 * @author liuqing
 * @date 2018-11-30
 * @version 0.1.0
 */
@Slf4j
public class DateUtil {

	
	private DateUtil() {
		super();
	}

	public static SimpleDateFormat DATE_SDF = new SimpleDateFormat("yyyy-MM-dd");

	public static final String DATE_FORMAT_19 = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_FORMAT_10 = "yyyy-MM-dd";
	public static final String DATE_FORMAT_6 = "yyyyMM";
	public static final String DATE_FORMAT_20 = "HH:mm";
	public static final String DATE_FORMAT_21 = "HH:mm:ss";
	public static final String DATE_FORMAT_22 = "yyyy-MM";
	public static final String DATE_FORMAT_11 = "yyyy-MM-dd HH:mm";
	public static final String DATE_FORMAT_15 = "yyMMddHHmmssSSS";

	public static String formatDate6(Date date) {
		return formatDateByFormat(date, DATE_FORMAT_6);
	}

	public static String formatDate(Date date) {
		return formatDateByFormat(date, DATE_FORMAT_10);
	}

	public static String formatDateByFormat(Date date, String format) {
		String result = "";
		if (date != null) {
			try {
				SimpleDateFormat sdf = new SimpleDateFormat(format);
				result = sdf.format(date);
			} catch (Exception ex) {
				log.error(ex.getMessage());
			}
		}
		return result;
	}

	public static Date parseDate(java.sql.Date date) {
		return date;
	}

	public static java.sql.Date parseSqlDate(Date date) {
		if (date != null) {
			return new java.sql.Date(date.getTime());
		} else {
			return null;
		}
	}

	public static String format(Date date, String format) {
		String result = "";
		try {
			if (date != null) {
				DateFormat df = new SimpleDateFormat(format);
				result = df.format(date);
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return result;
	}

	public static String format(Date date) {
		return format(date, "yyyy/MM/dd");
	}

	public static String format1(Date date) {
		return format(date, DATE_FORMAT_10);
	}

	public static String formatYYMM(Date date) {
		return format(date, DATE_FORMAT_22);
	}

	public static int getYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}

	public static int getMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH) + 1;
	}

	public static int getDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	public static int getHour(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.HOUR_OF_DAY);
	}

	public static int getMinute(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MINUTE);
	}

	public static int getSecond(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.SECOND);
	}

	public static long getMillis(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.getTimeInMillis();
	}

	public static int getWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
		dayOfWeek = dayOfWeek - 1;
		if (dayOfWeek == 0) {
			dayOfWeek = 7;
		}
		return dayOfWeek;
	}

	public static String getDate(Date date) {
		return format(date, "yyyy/MM/dd");
	}

	public static String getDate(Date date, String formatStr) {
		return format(date, formatStr);
	}

	public static String getTime(Date date) {
		return format(date, DATE_FORMAT_21);
	}

	public static String getDateTime(Date date) {
		return format(date, DATE_FORMAT_19);
	}

	/**
	 * 日期相加
	 * 
	 * @param date
	 *            Date
	 * @param day
	 *            int
	 * @return Date
	 */
	public static Date addDate(Date date, int day) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
		return c.getTime();
	}

    /**
     * 日期月份相加减
     * @param date 具体的时间
     * @param month 相加减的月份
     * @return 处理后的时间
     */
    public static Date addMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }

	/**
	 * 日期加减指定值
	 * @param date 原始日期
	 * @param calendarField 操作部分
	 * @param amount 操作值
	 * @return
	 */
	public static Date add(Date date, int calendarField,int amount) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int fieldValue = c.get(calendarField);
		fieldValue += amount;
		c.set(calendarField, fieldValue);
		return c.getTime();
	}

	/**
	 * 日期相减
	 * 
	 * @param date
	 *            Date
	 * @param date1
	 *            Date
	 * @return int
	 */
	public static int diffDate(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
	}

	/**
	 * 日期相减(返回秒值)
	 * 
	 * @param date
	 *            Date
	 * @param date1
	 *            Date
	 * @return int
	 * @author
	 */
	public static Long diffDateTime(Date date, Date date1) {
		return (Long) ((getMillis(date) - getMillis(date1)) / 1000);
	}

	/**
	 * 日期相减(返回小时)
	 * 
	 * @param date
	 *            Date
	 * @param date1
	 *            Date
	 * @return int
	 */
	public static int diffDateHour(Date date, Date date1) {
		return (int) ((getMillis(date) - getMillis(date1)) / (1000 * 3600));
	}

	public static Date getDate(String date) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_10);
		return sdf.parse(date);
	}

	public static Date getDate(String date, String formatStr) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		return sdf.parse(date);
	}

	public static Date getdate1(String date) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_19);
		return sdf.parse(date);
	}

	public static Date getMaxTimeByStringDate(String date) throws ParseException {
		String maxTime = date + " 23:59:59";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_19);
		return sdf.parse(maxTime);
	}

	/**
	 * 获得当前时间
	 * 
	 * @return
	 */
	public static Date getCurrentDateTime() {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_19);
		String result = DateUtil.getDateTime(date);
		try {
			return sdf.parse(result);
		} catch (ParseException e) {
			log.error(e.getMessage());
		}
		return null;

	}

	/**
	 * 获得当前时间
	 * 
	 * @return
	 */
	public static Date getCurrentDate() {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_10);
		String result = DateUtil.getDateTime(date);
		try {
			return sdf.parse(result);
		} catch (ParseException e) {
			log.error(e.getMessage());
		}
		return null;

	}

	public static String getCurrentDateTimeToStr() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.format(getCurrentDateTime());
	}

	public static String getCurrentDateTimeToStr2() {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_19);
		return sdf.format(getCurrentDateTime());
	}

	public static Long getWmsupdateDateTime() {
		Calendar cl = Calendar.getInstance();

		return cl.getTimeInMillis();
	}

	public static Integer getLeftSeconds(String date) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_19);
		Date condition = sdf.parse(date);
		long n = condition.getTime();
		long s = sdf.parse(getCurrentDateTimeToStr2()).getTime();
		return (int) ((s - n) / 1000);
	}

	/**
	 * 返回当月最后一天的日期
	 */
	public static Date getLastDayOfMonth(Date date) {
		Date theDate = parseToDate(getDate(date, "yyyy-MM-dd"), "yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(theDate);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		return calendar.getTime();
	}

    /**
     * 将日期转换为日历
     * @param date 日期
     * @return 日历
     */
    private static Calendar convert(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
	 * 获取最小日期
	 * @param params
	 * @return
	 */
	public static Date getMinDate(Date... params){
		Date minDate = params[0];
		for (int i = 1; i < params.length; i++) {
			if(minDate.after(params[i])){
				minDate = params[i];
			}
		}
		return minDate;
	}
	
	/**
	 * 获取最大日期
	 * @param params
	 * @return
	 */
	public static Date getMaxDate(Date... params){
		Date maxDate = params[0];
		for (int i = 1; i < params.length; i++) {
			if(maxDate.before(params[i])){
				maxDate = params[i];
			}
		}
		return maxDate;
	}
	
	/**
	 * 合并两个日期
	 * @param dateYmd 取年月日
	 * @param dateHms 取时分秒
	 * @return
	 */
	public static Date concatDate(Date dateYmd, Date dateHms){
		if(dateYmd == null || dateHms == null){
			return null;
		}
		Calendar ymdCal = Calendar.getInstance();
		ymdCal.setTime(dateYmd);
		Calendar hmsCal =  Calendar.getInstance();
		hmsCal.setTime(dateHms);
		hmsCal.set(ymdCal.get(Calendar.YEAR), ymdCal.get(Calendar.MONTH), ymdCal.get(Calendar.DAY_OF_MONTH));
		return hmsCal.getTime();
	}
	
	
	
	/**
	 * 校验是否为可转换的时间格式
	 * @param date ：时间字符串
	 * @return
	 */
	public  static boolean vaildFormat(String date) {
		try {
			SimpleDateFormat vaildFormat = new SimpleDateFormat(DATE_FORMAT_10);
			//设置后，严格过滤时间格式
			vaildFormat.setLenient(false);
			vaildFormat.parse(date);
			return true;
		} catch (Exception e) {
			return false;
		}
		
	}
	

	/**
	 * 判断是否是对应的格式的日期字符串
	 * @param dateStr
	 * @param datePattern
	 * @return
	 */
	public static boolean isRightDateStr(String dateStr,String datePattern){
		DateFormat dateFormat  = new SimpleDateFormat(datePattern);
		try {
			//采用严格的解析方式，防止类似 “2017-05-35” 类型的字符串通过
			dateFormat.setLenient(false);
			dateFormat.parse(dateStr);
			Date date = (Date)dateFormat.parse(dateStr);
			//重复比对一下，防止类似 “2017-5-15” 类型的字符串通过
			String newDateStr = dateFormat.format(date);
			if(dateStr.equals(newDateStr)){
				return true;
			}else {
				log.error("字符串dateStr:{}， 不是严格的 datePattern:{} 格式的字符串",dateStr,datePattern);
				return false;
			}
		} catch (ParseException e) {
			log.error("字符串dateStr:{}，不能按照 datePattern:{} 样式转换",dateStr,datePattern);
			return false;
		}
	}

	public static List<String> findDates(String start, String end) throws ParseException {

		List<String> dateTemp = new ArrayList<>();
		Date dBegin = DATE_SDF.parse(start);
		Date dEnd = DATE_SDF.parse(end);
		List<Date> lDate = new ArrayList<Date>();
		lDate.add(dBegin);
		Calendar calBegin = Calendar.getInstance();
		calBegin.setTime(dBegin);
		Calendar calEnd = Calendar.getInstance();
		calEnd.setTime(dEnd);
		while (dEnd.after(calBegin.getTime())) {
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(calBegin.getTime());
		}
		for (Date date : lDate) {
			dateTemp.add(DATE_SDF.format(date));
		}
		return dateTemp;
	}


	/**
	 * 将时间格式的字符串，转换为时间
	 *
	 * @param str 时间格式的字符串
	 * @param pattern 转换格式
	 * @return java.util.Date
	 */
	public static Date parseToDate(String str, String pattern) {
		DateFormat df = new SimpleDateFormat(pattern);
		try {
			return df.parse(str);
		} catch (ParseException e) {
		}
		return null;
	}




}